import { commonStyle, commonAttr } from "../ComponentList/list"
import { dataQuery, getDM } from "@/api/multidimensionalAnalysis"
import { analysisComponentTypes, fliterComponentTypes,analysisComponentUpdateTypes,filterTableFieldTypes } from "./const"
import { getComponentByKey, getComponentListByKeys, getComponentListByTypes } from "./utils"
import store from "@/store"

/**
 * 创建一个基础业务组件
 * @param { Model } model
 * @returns { Component }
 */
export function getBaseAnalysisComponent(model){
  // 获取所有的业务组件
  // const analysisComponentList = getAllAnalysisComponentByEditType(true)
  // 如果画布中已经存在这个组件
  // if(analysisComponentList.find(item => item.props.value.id === model.id)){
  //   return false
  // }
  model.params = {}
  // switch (model.chartType) {

  // }
  // 是不是交叉表
  const isCrossTable = Number(model.chartTypeId) === 1
  const component = {
    ...commonAttr,
    style: {
      ...commonStyle,
      width: 500,
      height: 300
    },
    id: "widget",
    tag: "c-widget",
    label: model.name,
    icon: "table",
    props: {
      widgetType: "Table",
      value: model,// getWidgetOpitons(params, data),
      loading: false,
      filterKeys: [], // 绑定的所有过滤组件key
      updateComponent: 0,
    },
    type: analysisComponentTypes.myAnalysis,
    isGeometry: true, // 是否拥有几何属性配置
    isData: false, // 是否拥有数据配置
    isStyle: false, // 是否拥有样式配置
    isEvent: false, // 是否拥有事件配置
    isLinkage: !isCrossTable, // 是否拥有联动配置
    isJump: !isCrossTable, // 是否拥有跳转配置
  }
  // console.log(data)
  return component
}

/**
 * 根据业务组件的value获取数据
 * @param { boolean } isPreview
 * @param { Model } model
 * @param { Key[] } filterKeys
 * @param {*} jumpFilterData
 * @returns
 */
export function getData(isPreview,model, filterKeys, jumpFilterData){
  const {
    previewData
  } = store.state.lowCode

  let filterData = []
  if(isPreview){
    const componentList = getComponentListByKeys(previewData.componentList, filterKeys)
    filterData = componentList.map(item => {
      const {
        filterField,value
      } = item.props
      if(filterField.length > 0){
        const arr = filterField[0].split("/")
        const colType = arr[4]
        const fliterNameType = getFilterType(colType, value)
        return {
          enName: arr[1],
          value,
          id: arr[2], // 字段id
          type: arr[3],
          fliterNameType
        }
      }

        return {}


    })
  }

  console.log(filterData)
  return new Promise((resolve, reject)=> {
    const params = getParams(model, filterData, jumpFilterData)
    dataQuery(params)
    .then(data => {
      if(data.errorCode === 0){
        resolve({
          params,
          data: data.data
        })
      }
      else {
        reject()
      }
    })
  })


}

/**
 * 获取过滤类型
 * @param { ColType } colType
 * @param { FilterType } value
 */
export function getFilterType (colType, value){
  let fliterNameType = filterTableFieldTypes.STRING
  if(colType === "STRING"){
    fliterNameType = filterTableFieldTypes.STRING
  }
  else if(colType === "INT") {
    fliterNameType = filterTableFieldTypes.INT
  }
  else if(colType === "DATETIME"){
    if(typeof value === "string"){
      fliterNameType = filterTableFieldTypes.DATETIME
    }
    else {
      fliterNameType = filterTableFieldTypes.DATETIMES
    }

  }
  return fliterNameType
}

/**
 * 获取业务组件的数据查询的参数
 * @param { Model } model
 * @param {*} filterData 过滤组件的过滤数据
 * @param {*} jumpFilterData 跳转设置的过滤数据
 * @returns
 */
export function getParams(model, filterData, jumpFilterData){
  const chartAxisData = getChartAxisData(model)
  const { databaseName, datasourceId, gradeThematicId, tableName } = chartAxisData.dataSource
  const globalFilter = []
  const {
    updateType,
    linkageFilterData
  } = store.state.lowCode
  // 跳转设置里的过滤条件
  if(jumpFilterData){
    // const fliterNameType = getFilterType(colType, value)
    globalFilter.push({
      ...jumpFilterData,
      filterGroups: {
        columnId: jumpFilterData.id,
        type: getFilterType(jumpFilterData.colType, jumpFilterData.value), // 包含
        value: jumpFilterData.value
      }
    })
  }

  // 过滤组件的过滤
  const filterComponent = () => {
    filterData.forEach(item => {

      if(!item.value || ( item.value instanceof Array && item.value.length === 0)){
        return
      }

      const newItem = {
        ...item,
        origin: 0,
        order: 0,
        // type: item.type, // 维度传1,指标传2,id = -1 传4
        filterGroups:  {
          columnId: item.id,
          type: item.fliterNameType,
          value: item.fliterNameType === filterTableFieldTypes.DATETIMES ? { "min": item.value[0],"max":item.value[1],"gt": 0/1 ,"lt":0/1} :item.value
        }
      }
      globalFilterPush(newItem)


    })
  }


  // 联动设置的过滤
  const linkageFilter = () => {
    linkageFilterData.forEach(item => {
      const {
        source,
        target,
        value
      } = item
      // 当前组件
      const curComponentFilter = target.find(element => element.key === model.componentPageId)
      if(!curComponentFilter){
        return
      }
      const {
        field,
        key,
        options,
        filterType,
        colType
      } = curComponentFilter
      const fliterNameType = getFilterType(colType, value)
      const option = options.find(optionItem => optionItem.value === field)
      const newItem = {
        enName: field,
        id: option.id,
        origin: 0,
        order: 0,
        type: option.filterType,
        filterGroups:  {
          columnId: option.id,
          type: fliterNameType,
          value: fliterNameType === filterTableFieldTypes.DATETIMES ? { "min": value[0],"max":value[1],"gt": 0/1 ,"lt":0/1} : value
        }
      }
      globalFilterPush(newItem)

    })
  }

  const globalFilterPush = newItem => {
    const index = globalFilter.findIndex(filter => filter.enName === newItem.enName)
    if(index > -1){
      globalFilter[index] = newItem
    }
    else {
      globalFilter.push(newItem)
    }
  }

  // 如果是由过滤组件引起的更新,则过滤组件的等级最高
  if(updateType === analysisComponentUpdateTypes.filterComponent){
    linkageFilter()
    filterComponent()
  }
  else {
    filterComponent()
    linkageFilter()
  }


  console.log(filterData, jumpFilterData, globalFilter)
  const params = {
    "chartType": Number(model.chartTypeId),// model.dasChartTypeId,
    "dataId": 1,
    "dataSource": {
      databaseName,
      datasourceId,
      gradeThematicId,
      tableName
    },
    dimensions: chartAxisData.dimensions,
    measures: chartAxisData.measures,
    globalFilter,
    name: model.name,
    "pageNum": 1,
    "pageSize": 10,
    "timeStamp": new Date().getTime(),
    "type": 1
  }

  return params
}

/**
 * 获取业务组件的chartAxisData
 * @param { Model } model
 * @returns { object}
 */
export function getChartAxisData(model){
  return JSON.parse(model.chartAxisData)
}


/**
 * 根据当前编辑状态(即是编辑还是预览)获取当前所有业务组件
 * @param {boolean} isEdit
 * @param { string[] } keys
 * @returns {component[]}
 */
export function getAllAnalysisComponentByEditType(isEdit, keys){
  const {
    canvasComponentList,
    previewData
  } = store.state.lowCode
  let componentList
  if(isEdit){
    componentList = canvasComponentList
  }
  else {
    componentList = previewData.componentList
  }
  if(keys){
    return getComponentListByKeys(componentList, keys)
  }

    const types = getAllAnalysisComponentTypes()
    return getComponentListByTypes(componentList, types)

}

/**
 * 获取业务组件的types
 * @returns {string[]}
 */
export function getAllAnalysisComponentTypes(){
  const types = []
  Object.keys(analysisComponentTypes).forEach(key => {
    types.push(analysisComponentTypes[key])
  })
  return types
}


/**
 * 触发所有业务组件的更新
 * @param { boolean } isEdit
 * @param { string[] } keys
 */
export function updateAllAnalysisComponent(isEdit, keys, updateType = analysisComponentUpdateTypes.filterComponent){
  store.commit("lowCode/setUpdateType", updateType)
  const analysisComponentList = getAllAnalysisComponentByEditType(isEdit, keys)
  analysisComponentList.forEach(item => {
    item.props.updateComponent += 1
  })
}


/**
 * 更新业务组件
 * @param {key | Component} key
 * @param {componentList} componentList
 */
export function updateAnalysisComponent(component, componentList){
  if(typeof key === "string") {
    component = getComponentByKey(componentList, component)
    component.props.updateComponent += 1
  }
  else {
    component.props.updateComponent += 1
  }
}

/**
 * 获取业务组件的所有字段
 * @param { Component } component
 */
export function getFieldListByComponent(component){
  const {
    params
  } = component.props.value
  return getFieldListByDimensionsAndMeasures(params.dimensions || [], params.measures || [])

}


/**
 * 根据维度和指标获取所有字段
 * @param {Field[]} dimensions
 * @param {Field[]} measures
 * @returns {FieldOption[]}
 */
export function getFieldListByDimensionsAndMeasures(dimensions = [], measures = []){
  const dimensionsList = dimensions.map(element => ({
      type: "field",
      label: `${element.name}`,
      value: `${element.enName}`,
      colType: element.colType,
      id: element.id,
      filterType: element.id === -1 ? 4 : 1
    })) || []
  const measuresList = measures.map(element => ({
      type: "field",
      label: `${element.name}`,
      value: `${element.enName}`,
      colType: element.colType,
      id: element.id,
      filterType: 2
    })) || []
  return [
    ...dimensionsList,
    ...measuresList.filter(measure => dimensionsList.findIndex(dimension => dimension.value === measure.value) === -1)
  ]
}

/**
 * 过滤字段的类型
 * @param { Filed[] } fieldList
 * @param { ColType[] } fieldTypes
 */
export function filterFieldTypes(fieldList, fieldTypes){
  return fieldList.filter(item => fieldTypes.includes(item.colType))
}


/**
 * 获取多个业务组件的所有字段
 * @param { Component[] } componentList 业务组件的组件列表
 * @param { boolean } isTable 是否去组件相关表的所有字段
 * @param { GroupOption[] } fieldTypes 过滤的字段类型
 */
export function getFieldListByComponentList(componentList, isTable, fieldTypes){

    const list = []

    if(isTable){
      const tableCodeList = componentList.map(component => {
        const {
          name,
          tableCode,
          datasourceId
        } = component.props.value
        return {
          name,
          tableCode,
          datasourceId,
          key: component.key
        }
      })
      return new Promise((resolve, reject)=> {
        Promise.all(tableCodeList.map(getTableField))
        .then(res => {
          res.forEach(item => {
            const {
              dimensions,
              measures
            } = item.data
            const children = getFieldListByDimensionsAndMeasures(dimensions, measures)
            list.push(createGroupOption(item.name, item.key,filterFieldTypes(children, fieldTypes)))
          })
          resolve(list)

        })
      })
    }

      componentList.forEach(component => {
        const {
          name,
        } = component.props.value
        const children = getFieldListByComponent(component)
        list.push(createGroupOption(name, component.key,filterFieldTypes(children, fieldTypes)))

      })
      return list






}

/**
 * 根据接口获取表的所有字段
 * @param {*} param0
 * @returns
 */
export function getTableField ({tableCode, datasourceId, name, key}) {
  return new Promise((resolve, reject)=> {
    getFieldListByTableCode(tableCode, datasourceId)
    .then(res =>
      resolve({data: res.data, name, key})
    )
  })
}


/**
 * 创建一个GroupOption
 * @param { string } label
 * @param { string } value
 * @param { Field[] } children
 * @returns { GroupOption }
 */
export function createGroupOption(label, value, children){
  return {
    type: "group",
    label,
    value,
    children
  }
}



/**
 * 根据表查询所有字段
 * @param { string } tableCode
 */
export async function getFieldListByTableCode(tableCode, datasourceId){
  return new Promise((resolve, reject)=> {
    getDM({
      datasourceId,
      tableCode
    })
    .then(data => {
      resolve({
        ...data
      })
    })
  })

}

/**
 * 设置多个业务组价的联动设置
 * @param {Component[]} analysisComponentList
 */
export function setAnalysisComponentListLinkage(analysisComponentList){
  analysisComponentList.forEach(component => {
    const {
      source, // 源字段(关联字段)
      componentList, // 目标组件字段列表
    } = component.linkage
    const newComponentList = analysisComponentList.filter(item => item.key !== component.key).map(item => {
      const oldComponent = componentList.find(element => element.key === item.key)
      return {
        key: item.key,
        name: item.props.value.name,
        field: oldComponent ? oldComponent.field : undefined,
        options: getFieldListByComponent(item),
        isCheck: oldComponent ? oldComponent.isCheck : false
      }

    })
    component.linkage.componentList = newComponentList
  })
}
